package container;

import java.io.*;

/**
 * 自定义类加载器，需要重写findClass，然后通过调用loadClass进行类加载（loadClass通过递归实现类的双亲委派加载）
 */
public class MyClassLoader extends ClassLoader {

    /**
     * 设置类的路径
     */
    private String root;

    MyClassLoader(String root){
        this.root = root;
    }


    protected Class<?> findClass(String name) throws ClassNotFoundException {
        byte[] classData = loadClassData(name);
        if (classData == null) {
            throw new ClassNotFoundException();
        } else {
            return defineClass(name, classData, 0, classData.length);
        }
    }

    private byte[] loadClassData(String className) {
        String fileName = root + File.separatorChar
                + className.replace('.', File.separatorChar) + ".class";
        InputStream ins = null;
        try {
            ins = new FileInputStream(fileName);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int bufferSize = 1024;
            byte[] buffer = new byte[bufferSize];
            int length = 0;
            while ((length = ins.read(buffer)) != -1) {
                baos.write(buffer, 0, length);
            }
            return baos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                ins.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }


    public void setRoot(String root) {
        this.root = root;
    }

    public static void main(String[] args) {

        MyClassLoader classLoader = new MyClassLoader("C:\\temp");

        Class<?> testClass = null;
        try {
            testClass = classLoader.loadClass("com.daxin.classloader.StaticClassDemo");
            Object object = testClass.newInstance();
            System.out.println(object.getClass().getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}
